package com.lsk.serviceprice.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lsk.internalcommon.DTO.PriceRule;
import com.lsk.internalcommon.DTO.ResponseResult;
import com.lsk.internalcommon.constant.CommonStatusEnum;
import com.lsk.internalcommon.request.ForecastPriceDTO;
import com.lsk.internalcommon.response.DirectionResponse;
import com.lsk.internalcommon.response.ForecastPriceResponse;
import com.lsk.internalcommon.util.BigDecimalUtils;
import com.lsk.serviceprice.mapper.PriceRuleMapper;
import com.lsk.serviceprice.remote.ServiceMapClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;

@Service
@Slf4j
public class ForecastPriceService {
    @Autowired
    private ServiceMapClient serviceMapClient;

    @Autowired
    private PriceRuleMapper priceRuleMapper;

    public ResponseResult forecastPrice(String deplongitude,String deplatitude,String destlongitude,String destlatitude,String cityCode,String vehicleType){
        log.info("出发地经度："+deplongitude);
        log.info("出发地纬度："+deplatitude);
        log.info("目的地经度："+destlongitude);
        log.info("目的地纬度："+destlatitude);

        log.info("调用地图服务，获取距离和时长");
        ForecastPriceDTO forecastPriceDTO = new ForecastPriceDTO();
        forecastPriceDTO.setDeplongitude(deplongitude);
        forecastPriceDTO.setDeplatitude(deplatitude);
        forecastPriceDTO.setDestlongitude(destlongitude);
        forecastPriceDTO.setDestlatitude(destlatitude);
        //通过调用map服务，根据出发地和目的地计算出大约距离和大约时长
        ResponseResult<DirectionResponse> driving = serviceMapClient.driving(forecastPriceDTO);
        Integer distance = driving.getData().getDistance();
        Integer duration = driving.getData().getDuration();
        log.info("距离："+distance+",时间"+duration);
        log.info("获取计价规则");
        HashMap<String, Object> map = new HashMap<>();
        map.put("city_code",cityCode);
        map.put("vehicle_type",vehicleType);

        QueryWrapper<PriceRule> wrapper = new QueryWrapper<>();
        wrapper.eq("city_code",cityCode);
        wrapper.eq("vehicle_type",vehicleType);
        wrapper.orderByDesc("fare_version");
        //根据城市编码和选择的车型去获取到计价规则
        List<PriceRule> priceRules = priceRuleMapper.selectList(wrapper);
        if (priceRules.size()==0){
            return ResponseResult.fail(CommonStatusEnum.PRICE_RULE_NOT_EXIT.getCode(),CommonStatusEnum.PRICE_RULE_NOT_EXIT.getValue());
        }
        PriceRule priceRule = priceRules.get(0);
        log.info("根据距离，时长和计价规则得到预估价格");
        double price = getPrice(distance, duration, priceRule);

        ForecastPriceResponse priceResponse = new ForecastPriceResponse();
        priceResponse.setPrice(price);
        priceResponse.setCityCode(cityCode);
        priceResponse.setVehicleType(vehicleType);
        return ResponseResult.success(priceResponse);
    }

    /**
     * 根据距离，时长，计价规则计算出价格
     * @param distance
     * @param duration
     * @param priceRule
     * @return
     */
    private  double getPrice(Integer distance, Integer duration,PriceRule priceRule){
        //总价格
        double price = 0;
        //起步价
        Double startFare = priceRule.getStartFare();
        price = BigDecimalUtils.add(price, startFare);

        //---------  算出里程数 和里程数价格---------
        //总里程数 千米
        double distanceDecimal = BigDecimalUtils.divide(distance,1000);
        //需要计价的里程数
        double startMile = (double)priceRule.getStartMile();
        double distanceSubtract = BigDecimalUtils.subtract(distanceDecimal,startMile);
        //最终里程数的价格
        double mile = distanceSubtract<0 ? 0 :distanceSubtract;
        double unitPricePerMile = priceRule.getUnitPricePerMile();
        double mileFare = BigDecimalUtils.multiply(mile,unitPricePerMile);
        price = BigDecimalUtils.add(price,mileFare);

        //需要计价的时长
        double minuteDecimal = BigDecimalUtils.divide(duration,60);
        double unitPricePerMinute = priceRule.getUnitPricePerMinute();
        //最终时长的价格
        double timeFare = BigDecimalUtils.multiply(minuteDecimal,unitPricePerMinute);
        price = BigDecimalUtils.add(price,timeFare);

        return price;
    }

}
